<template>
  <el-dialog
      class="mor-dialog"
      v-model="visible"
      v-bind="{...$props, ...$attrs}"
      @close="emits('close')"
      @keydown.esc="handleCancel()"
  >
    <template #header>
      <div>
        <slot name="title" :data="$data">
          <el-text size="large" tag="b">{{ __title }}</el-text>
        </slot>
        <slot name="sub-title" :data="$data">
          <template v-if="$subTitle">
            <el-divider direction="vertical"></el-divider>
            <el-text tag="b" type="info">{{ __subTitle }}</el-text>
          </template>
        </slot>
      </div>
      <div>
        <template v-if="hasHeader">
          <slot name="header" :data="$data"></slot>
          <el-divider direction="vertical"></el-divider>
        </template>
        <el-button
            size="small"
            style="padding: 3px 6px"
            type="danger"
            :disabled="loading"
            @click="handleCancel"
        >
          <fa icon="close"></fa>
        </el-button>
      </div>
    </template>
    <template #default>
      <div
          v-loading="loading"
          class="mor-dialog-body"
          element-loading-background="rgba(0,0,0,0.1)"
          element-loading-text="加载中..."
      >
        <slot :data="$data"></slot>
      </div>
    </template>
    <template #footer v-if="showFooter">
      <el-space>
        <slot v-if="hasFooter" name="footer" :data="$data"/>
        &nbsp;
      </el-space>
      <el-space v-if="confirm">
        <el-button
            type="success"
            :disabled="loading"
            @click="handleConfirm"
        >
          {{ confirmButtonText }}
        </el-button>
        <el-button
            type="info"
            @click="handleCancel"
            :disabled="loading"
        >
          {{ cancelButtonText }}
        </el-button>
      </el-space>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">

import {computed, ref, useSlots} from "vue";
import _ from 'lodash'

import {morDialogPropsDefault, type MorDialogProps} from "../../types/dialog.types.ts";

// 已从types/dialog.types.ts导入MorDialogProps接口，无需重复定义

let emits = defineEmits(['close', 'update:title', 'update:subTitle', 'update:modelValue'])
let props = withDefaults(
    defineProps<MorDialogProps>(),
    morDialogPropsDefault
)

/**
 * 功能区
 */
const slots = useSlots();
const hasHeader = computed(() => !!slots.header)
const hasFooter = computed(() => !!slots.footer)
const showFooter = hasFooter.value || !!props.confirm


const loading = ref(false)
const $data: any = ref({})
const __title = ref('')
const __subTitle = ref('')
const $title = computed({
  get: () => props.title,
  set: (v) => {
    emits('update:title', v)
    __title.value = v || '对话框'
  }
})
const $subTitle = computed({
  get: () => props.subTitle,
  set: (v) => {
    emits('update:subTitle', v)
    __subTitle.value = v || ''
  }
})

const $origin = ref({})

// 将visible与modelValue同步
const visible = computed({
  get: () => props.modelValue,
  set: (value) => {
    emits('update:modelValue', value)
  }
})

export type MorDialogConfig = {
  title: string,
  subTitle: string
}

function open(data: any = {}, config?: MorDialogConfig) {
  if (config) {
    const {title, subTitle} = config
    $title.value = title
    $subTitle.value = subTitle
  }
  $origin.value = data
  $data.value = _.cloneDeep(data)
  emits('update:modelValue', true)
}

function close() {
  loading.value = false
  emits('update:modelValue', false)
}

function handleConfirm() {
  loading.value = true
  props.confirm && props.confirm($data.value, close)
}

function handleCancel() {
  loading.value = true
  if (props.cancel) {
    props.cancel($data.value, close)
  } else {
    close()
  }
}

defineExpose({open, close})

</script>

<style>
.mor-dialog {
  border: 2px solid #aaaaaa;
}

.mor-dialog-modal {
  background-color: rgba(4, 33, 71, 0.15) !important;
}

.mor-dialog-header {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  padding-left: 5px;
}

.mor-dialog-body-wrapper {
  padding: 0;
  background-color: transparent;
}

.mor-dialog-body {
  background-color: #ffffff;
}

.mor-dialog-footer {
  color: #aaa;
  padding-left: 5px;
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
}
</style>